package com.beauty.payment.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.beauty.payment.client.OrderClient;
import com.beauty.payment.config.AlipayConfig;
import com.beauty.payment.dto.PaymentRequest;
import com.beauty.payment.dto.PaymentResponse;
import com.beauty.payment.entity.Payment;
import com.beauty.payment.entity.PaymentRecord;
import com.beauty.payment.repository.PaymentRecordRepository;
import com.beauty.payment.repository.PaymentRepository;
import com.beauty.payment.service.PaymentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class PaymentServiceImpl implements PaymentService {

    private final PaymentRecordRepository paymentRecordRepository;
    private final PaymentRepository paymentRepository;
    private final AlipayClient alipayClient;
    private final AlipayConfig alipayConfig;
    private final OrderClient orderClient;
    
    @Override
    @Transactional
    public Long recordPaymentRequest(String orderNumber, BigDecimal amount, String paymentMethod) {
        log.info("【支付服务】记录支付请求: 订单号={}, 金额={}, 支付方式={}", orderNumber, amount, paymentMethod);
        
        // 检查是否已存在成功的支付记录
        if (isOrderPaid(orderNumber)) {
            log.warn("【支付服务】订单已支付，不再创建支付记录: {}", orderNumber);
            return null;
        }
        
        // 创建支付记录
        PaymentRecord record = new PaymentRecord();
        record.setOrderNumber(orderNumber);
        record.setAmount(amount);
        record.setPaymentMethod(paymentMethod);
        record.setStatus("PENDING");
        record.setCreateTime(LocalDateTime.now());
        
        PaymentRecord savedRecord = paymentRecordRepository.save(record);
        log.info("【支付服务】支付记录已创建: ID={}", savedRecord.getId());
        
        return savedRecord.getId();
    }

    @Override
    @Transactional
    public boolean handlePaymentSuccess(String orderNumber, String tradeNo, BigDecimal amount, String paymentMethod) {
        log.info("【支付服务】处理支付成功: 订单号={}, 交易号={}, 金额={}, 支付方式={}", 
                orderNumber, tradeNo, amount, paymentMethod);
        
        try {
            // 先检查是否已经有成功的记录
            boolean alreadyPaid = paymentRecordRepository.existsByOrderNumberAndStatus(orderNumber, "SUCCESS");
            if (alreadyPaid) {
                log.info("【支付服务】订单已存在成功支付记录，跳过处理: {}", orderNumber);
                return true;
            }
            
            // 查找该订单的所有支付记录
            List<PaymentRecord> pendingRecords = paymentRecordRepository.findByOrderNumber(orderNumber);
            
            PaymentRecord recordToUpdate = null;
            
            if (pendingRecords.isEmpty()) {
                // 如果没有找到记录，则创建新记录
                recordToUpdate = new PaymentRecord();
                recordToUpdate.setOrderNumber(orderNumber);
                recordToUpdate.setAmount(amount);
                recordToUpdate.setPaymentMethod(paymentMethod);
                recordToUpdate.setCreateTime(LocalDateTime.now());
            } else {
                // 使用第一条记录
                recordToUpdate = pendingRecords.get(0);
                
                // 将其他记录标记为CLOSED
                if (pendingRecords.size() > 1) {
                    log.warn("【支付服务】订单存在多条支付记录，将除第一条外的记录标记为CLOSED: {}", orderNumber);
                    for (int i = 1; i < pendingRecords.size(); i++) {
                        PaymentRecord duplicateRecord = pendingRecords.get(i);
                        duplicateRecord.setStatus("CLOSED");
                        duplicateRecord.setUpdateTime(LocalDateTime.now());
                        paymentRecordRepository.save(duplicateRecord);
                    }
                }
            }
            
            // 更新支付记录状态
            recordToUpdate.setTradeNo(tradeNo);
            recordToUpdate.setStatus("SUCCESS");
            recordToUpdate.setUpdateTime(LocalDateTime.now());
            paymentRecordRepository.save(recordToUpdate);
            
            // 调用订单服务更新订单状态
            try {
                if (orderClient != null) {
                    // 直接通过订单号更新订单状态
                    orderClient.updateOrderStatusByOrderNumber(orderNumber, "PAID");
                    log.info("【支付服务】订单状态已更新为已支付: 订单号={}", orderNumber);
                } else {
                    log.warn("【支付服务】OrderClient未注入，无法更新订单状态");
                }
            } catch (Exception e) {
                log.error("【支付服务】更新订单状态失败", e);
                // 不影响支付成功的处理，记录异常并继续
            }
            
            return true;
        } catch (Exception e) {
            log.error("【支付服务】处理支付成功时发生异常", e);
            return false;
        }
    }

    @Override
    public boolean isOrderPaid(String orderNumber) {
        return paymentRecordRepository.existsByOrderNumberAndStatus(orderNumber, "SUCCESS");
    }

    @Override
    public boolean closePayment(String orderNumber) {
        log.info("【支付服务】关闭支付订单: {}", orderNumber);
        
        try {
            // 关闭本地支付记录
            List<PaymentRecord> pendingRecords = paymentRecordRepository.findByOrderNumber(orderNumber);
            
            // 将所有PENDING状态的记录改为CLOSED
            for (PaymentRecord record : pendingRecords) {
                if ("PENDING".equals(record.getStatus())) {
                    record.setStatus("CLOSED");
                    record.setUpdateTime(LocalDateTime.now());
                    paymentRecordRepository.save(record);
                }
            }
            
            log.info("【支付服务】本地支付记录已关闭: {}", orderNumber);
            
            // 关闭支付宝订单
            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
            Map<String, Object> bizContent = new HashMap<>();
            bizContent.put("out_trade_no", orderNumber);
            request.setBizContent(com.alibaba.fastjson.JSON.toJSONString(bizContent));
            
            AlipayTradeCloseResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                log.info("【支付服务】支付宝订单关闭成功: {}", orderNumber);
                return true;
            } else {
                log.warn("【支付服务】支付宝订单关闭失败: {}, {}", response.getCode(), response.getMsg());
                return false;
            }
        } catch (Exception e) {
            log.error("【支付服务】关闭支付订单异常", e);
            return false;
        }
    }

    @Override
    public boolean verifyAlipaySign(Map<String, String> params) {
        try {
            return AlipaySignature.rsaCheckV1(
                    params, 
                    alipayConfig.getALIPAY_PUBLIC_KEY(), 
                    alipayConfig.getCHARSET(), 
                    alipayConfig.getSIGN_TYPE());
        } catch (AlipayApiException e) {
            log.error("【支付服务】验证支付宝签名异常", e);
            return false;
        }
    }

    @Override
    public List<PaymentResponse> getPaymentsByOrderId(String orderId) {
        log.info("【支付服务】查询订单支付记录: {}", orderId);
        List<Payment> payments = paymentRepository.findByOrderId(orderId);
        return payments.stream()
                .map(PaymentResponse::fromEntity)
                .collect(Collectors.toList());
    }
    
    @Override
    public PaymentResponse getPaymentById(Long id) {
        log.info("【支付服务】查询支付记录详情: {}", id);
        return paymentRepository.findById(id)
                .map(PaymentResponse::fromEntity)
                .orElse(null);
    }
    
    @Override
    @Transactional
    public PaymentResponse createPayment(PaymentRequest paymentRequest) {
        log.info("【支付服务】创建支付: {}", paymentRequest);
        
        // 检查是否已支付
        if (isOrderPaid(paymentRequest.getOrderId())) {
            log.warn("【支付服务】订单已支付，不再创建支付: {}", paymentRequest.getOrderId());
            Payment existingPayment = paymentRepository.findByOrderIdAndStatus(
                    paymentRequest.getOrderId(), Payment.PaymentStatus.SUCCESS).orElse(null);
            if (existingPayment != null) {
                return PaymentResponse.fromEntity(existingPayment);
            }
            return null;
        }
        
        // 创建支付记录
        Payment payment = new Payment();
        payment.setOrderId(paymentRequest.getOrderId());
        payment.setAmount(paymentRequest.getAmount());
        payment.setCurrency(paymentRequest.getCurrency());
        payment.setPaymentMethod(paymentRequest.getPaymentMethod());
        payment.setStatus(Payment.PaymentStatus.PENDING);
        payment.setCustomerId(paymentRequest.getCustomerId());
        payment.setPaymentDate(LocalDateTime.now());
        
        Payment savedPayment = paymentRepository.save(payment);
        log.info("【支付服务】支付已创建: ID={}", savedPayment.getId());
        
        // 记录支付请求
        recordPaymentRequest(
                paymentRequest.getOrderId(), 
                paymentRequest.getAmount(), 
                paymentRequest.getPaymentMethod()
        );
        
        return PaymentResponse.fromEntity(savedPayment);
    }
    
    @Override
    public List<PaymentResponse> getPaymentsByCustomerId(String customerId) {
        log.info("【支付服务】查询客户支付记录: {}", customerId);
        List<Payment> payments = paymentRepository.findByCustomerId(customerId);
        return payments.stream()
                .map(PaymentResponse::fromEntity)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<PaymentResponse> getAllPayments() {
        log.info("【支付服务】查询所有支付记录");
        List<Payment> payments = paymentRepository.findAll();
        return payments.stream()
                .map(PaymentResponse::fromEntity)
                .collect(Collectors.toList());
    }
    
    @Override
    @Transactional
    public PaymentResponse updatePaymentStatus(Long id, Payment.PaymentStatus status) {
        log.info("【支付服务】更新支付状态: ID={}, 状态={}", id, status);
        Payment payment = paymentRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("支付记录不存在: " + id));
        
        payment.setStatus(status);
        payment.setUpdatedAt(LocalDateTime.now());
        
        // 如果状态为成功，设置支付时间
        if (status == Payment.PaymentStatus.SUCCESS) {
            payment.setPaymentDate(LocalDateTime.now());
            
            // 如果有订单号，更新订单状态
            if (payment.getOrderId() != null) {
                try {
                    // 直接通过订单号更新订单状态
                    String orderNumber = payment.getOrderId();
                    orderClient.updateOrderStatusByOrderNumber(orderNumber, "PAID");
                    log.info("【支付服务】订单状态已更新为已支付: 订单号={}", orderNumber);
                } catch (Exception e) {
                    log.error("【支付服务】更新订单状态失败", e);
                    // 不影响支付状态更新，记录异常并继续
                }
            }
        }
        
        Payment savedPayment = paymentRepository.save(payment);
        return PaymentResponse.fromEntity(savedPayment);
    }
    
    @Override
    @Transactional
    public void deletePayment(Long id) {
        log.info("【支付服务】删除支付记录: {}", id);
        if (paymentRepository.existsById(id)) {
            paymentRepository.deleteById(id);
        } else {
            throw new RuntimeException("支付记录不存在: " + id);
        }
    }
} 